package com.nuanshui.heatedloan.credit.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.nuanshui.framework.consts.TransactionManagerType;
import com.nuanshui.framework.lang.DateUtil;
import com.nuanshui.framework.lang.SysStringUtils;
import com.nuanshui.framework.security.DESC;
import com.nuanshui.framework.springContext.SpringPropertiesUtil;
import com.nuanshui.framework.utils.redis.JedisUtil;
import com.nuanshui.heatedloan.baseservice.model.UserAgent;
import com.nuanshui.heatedloan.baseservice.service.CommonServiceImpl;
import com.nuanshui.heatedloan.constant.DubboCacheRegion;
import com.nuanshui.heatedloan.constant.GlobalParam;
import com.nuanshui.heatedloan.constant.RabbitMqQueue;
import com.nuanshui.heatedloan.constant.ServiceConstant;
import com.nuanshui.heatedloan.credit.constant.*;
import com.nuanshui.heatedloan.credit.facade.*;
import com.nuanshui.heatedloan.credit.facade.job.PayOrderJobService;
import com.nuanshui.heatedloan.credit.facade.third.party.RiskManagerInteractionService;
import com.nuanshui.heatedloan.credit.form.CustomerCreditAuditForm;
import com.nuanshui.heatedloan.credit.form.PayOrderInfoForm;
import com.nuanshui.heatedloan.credit.model.*;
import com.nuanshui.heatedloan.credit.msg.CreditPushConstant;
import com.nuanshui.heatedloan.credit.msg.CreditPushMsgService;
import com.nuanshui.heatedloan.credit.pay.PayInformPara;
import com.nuanshui.heatedloan.credit.pay.PayRequest;
import com.nuanshui.heatedloan.credit.pay.PayResult;
import com.nuanshui.heatedloan.credit.pay.TransRequestCode;
import com.nuanshui.heatedloan.credit.pay.constant.OrderPayState;
import com.nuanshui.heatedloan.credit.request.ApplyLoanRequest;
import com.nuanshui.heatedloan.credit.request.IdCardInfo;
import com.nuanshui.heatedloan.credit.request.OrderJobParams;
import com.nuanshui.heatedloan.credit.response.*;
import com.nuanshui.heatedloan.credit.utils.CalculateLoanAmt;
import com.nuanshui.heatedloan.credit.utils.Sequence;
import com.nuanshui.heatedloan.credit.utils.UserAgentUtil;
import com.nuanshui.heatedloan.credit.vo.CustomerBankCardInfoVO;
import com.nuanshui.heatedloan.credit.vo.CustomerBlackListVO;
import com.nuanshui.heatedloan.credit.vo.CustomerCreditResultVO;
import com.nuanshui.heatedloan.credit.vo.PayOrderInfoVO;
import com.nuanshui.heatedloan.dubbo.extension.cache.manager.DubboCacheManager;
import com.nuanshui.heatedloan.middleware.rabbitmq.RabbitmqMessageSender;
import com.nuanshui.heatedloan.msgcenter.facade.AppPushMsgService;
import com.nuanshui.heatedloan.msgcenter.facade.VerificationFacade;
import com.nuanshui.heatedloan.msgcenter.integration.CreditPushMsgBody;
import com.nuanshui.heatedloan.msgcenter.model.AliSmsSecurityCodeTemplateEnum;
import com.nuanshui.heatedloan.task.facade.constant.TaskEnum;
import com.nuanshui.heatedloan.userinfo.model.SimpleUserInfo;
import com.nuanshui.heatedloan.userinfo.tool.UserTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by wangxw on 2017/7/12.
 */
@Service(ServiceConstant.APPLYORDERSERVICE)
@Transactional(readOnly=true,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
public class ApplyOrderServiceImpl extends CommonServiceImpl implements ApplyOrderService {

    private Logger logger= LoggerFactory.getLogger(ApplyOrderServiceImpl.class);


    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private CustomerCreditResultService customerCreditResultService;

    @Autowired
    private CustomerProduceService customerProduceService;

    @Autowired
    private PayOrderInfoService payOrderInfoService;

    @Autowired
    private ZeroDayInfoService zeroDayInfoService;

    @Autowired
    private CustomerBlackListService customerBlackListService;

    @Autowired
    private RabbitmqMessageSender rabbitmqMessageSender;

    @Autowired
    private AllinPayTransService allinPayTransService;

    @Reference(url=GlobalParam.USER_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.USER_DUBBO_SERVER_VERSION)
    private UserTool userTool;

    @Reference(url= GlobalParam.MSGCENTER_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version=GlobalParam.MSGCENTER_DUBBO_SERVER_VERSION )
    private AppPushMsgService appPushMsgService;

    @Reference(url = GlobalParam.MSGCENTER_DUBBO_SERVER, timeout = GlobalParam.DUBBO_SERVER_TIME_OUT,version=GlobalParam.MSGCENTER_DUBBO_SERVER_VERSION )
    private VerificationFacade veriFacade;

    @Autowired
    private RiskManagerInteractionService riskManagerInteractionService;

    @Autowired
    private CreditPushMsgService creditPushMsgService;

    @Autowired
    private PayOrderJobService payOrderJobService;

    @Autowired
    private CustomerCreditAuditService customerCreditAuditService;

    @Autowired
    private CustomerBankCardInfoService customerBankCardInfoService;

    @Autowired
    private DubboCacheManager dubboCacheManager;


    public SingleLoanPageResponse getSingleLoanPageData(String userId){
        SingleLoanPageResponse singleLoanPageResponse=new SingleLoanPageResponse();
        Map<String,Object> map=new HashMap<String,Object>();
        //第一步调用产品表哪属性
        SingleLoanProductInfo singleLoanProductInfo =customerProduceService.getSingleLoanProductInfo();
        //第二步调用授权结果表哪信息
        CustomerCreditResultVO customerCreditResultVO=customerCreditResultService.loadVOByUserId(userId);
        if(customerCreditResultVO==null||customerCreditResultVO!=null&&customerCreditResultVO.getStatus()==1){
            return singleLoanPageResponse;
        }
        singleLoanPageResponse.setBaseRate(singleLoanProductInfo.getBaseRate());//单期贷基本利率
        singleLoanPageResponse.setSingleAmt(customerCreditResultVO.getSingleAmt()); //单期贷总金额
        //第一步调用订单表返回用户状态数据
        //查询在单期在还款之前的所有的订单
        List<PayOrderInfoVO> beforeReturnsPayOrderInfoVOs=new ArrayList<PayOrderInfoVO>();
        beforeReturnsPayOrderInfoVOs=payOrderInfoService.loadSingleLoanBeforeReturn(userId);
        int noPayAmt=0;
        for(PayOrderInfoVO payOrderInfoVO:beforeReturnsPayOrderInfoVOs){
            if(payOrderInfoVO.getOrderStatus()==OrderType.REVIEWORDER){
                singleLoanPageResponse.setStatus(payOrderInfoVO.getOrderStatus());
                singleLoanPageResponse.setLoanAmt(payOrderInfoVO.getLoanAmount());
                singleLoanPageResponse.setOrderAmt(payOrderInfoVO.getOrderAmount());
                singleLoanPageResponse.setLoadDays(payOrderInfoVO.getLoadDays());
                singleLoanPageResponse.setApplyTime(payOrderInfoVO.getCreatedAt().getTime());
                return singleLoanPageResponse;
            }
            if( payOrderInfoVO.getOrderStatus()==OrderType.LENDINGORDER||
                    payOrderInfoVO.getOrderStatus()==OrderType.APPROVEDORDER){
                singleLoanPageResponse.setStatus(OrderType.LENDINGORDER);
                singleLoanPageResponse.setLoanAmt(payOrderInfoVO.getLoanAmount());//贷款的金额
                singleLoanPageResponse.setOrderAmt(payOrderInfoVO.getOrderAmount()); //加上利息的总金额
                singleLoanPageResponse.setLoadDays(payOrderInfoVO.getLoadDays()); //贷款天数
                singleLoanPageResponse.setApplyTime(payOrderInfoVO.getCreatedAt().getTime());
                singleLoanPageResponse.setApprovedTime(payOrderInfoVO.getApprovedTime().getTime());
                return singleLoanPageResponse;
            }
            if(OrderType.OVERDUEPAYMENT==payOrderInfoVO.getOrderStatus()||
                    payOrderInfoVO.getOrderStatus()==OrderType.NOREIMBURSEMENT ||
                    payOrderInfoVO.getOrderStatus() == OrderType.REPAYING){
                noPayAmt=noPayAmt+payOrderInfoVO.getLoanAmount();
            }
            //本产品有在审核中或者放款中的订单
        }
        int singleAmt=customerCreditResultVO.getSingleAmt();//用户单期贷总额度
        int allAmt=customerCreditResultVO.getTotalAmt();//总金额
        int remainAmt=singleAmt-noPayAmt<0?0:singleAmt-noPayAmt; //剩余金额
        singleLoanPageResponse.setProductLimit(singleLoanProductInfo.getProductLimit());
        if(remainAmt< singleLoanProductInfo.getProductLimit()){
            singleLoanPageResponse.setLimitAmt(customerCreditResultVO.getSingleAmt());
            singleLoanPageResponse.setRemainAmt(remainAmt<allAmt?remainAmt:allAmt);
            singleLoanPageResponse.setStatus(2);
            //放列表
            //余额不足的时候
            List<PayOrderInfoVO> list=new ArrayList<>();
            list=payOrderInfoService.loadSingleLoanNoPay(userId,BorrowType.SINGLELOAN);
            for(PayOrderInfoVO payOrderInfoVO:list){
                payOrderInfoVO.setPayAmount(payOrderInfoVO.getOrderAmount()+payOrderInfoVO.getOverdueFee());
           if(OrderType.NOREIMBURSEMENT ==payOrderInfoVO.getOrderStatus()){
               int remainDay= payOrderInfoVO.getLoadDays()-(int)DateUtil.getIntervalDay(payOrderInfoVO.getLendTime(), Calendar.getInstance().getTime());
               payOrderInfoVO.setRemainDay(remainDay>0?remainDay:0);
               logger.info("----------剩余天数:"+payOrderInfoVO.getLoadDays());
               logger.info("----------剩余天数:"+payOrderInfoVO.getRemainDay());
           }
                }
            singleLoanPageResponse.setList(list);
            return singleLoanPageResponse;
        }
        //查询闪电贷 分期贷中有放款前的状态
        singleLoanPageResponse.setQuotaGradient(singleLoanProductInfo.getQuotaGradient());
        singleLoanPageResponse.setNumberGradient(singleLoanProductInfo.getNumberGradient());
        singleLoanPageResponse.setMinLoanDay(singleLoanProductInfo.getMinLoanDay());
        singleLoanPageResponse.setMaxLoanDay(singleLoanProductInfo.getMaxLoanDay());
        singleLoanPageResponse.setRemainAmt(remainAmt);
        singleLoanPageResponse.setSingleRate(customerCreditResultVO.getSingleRate());
           //单期贷款金额
        List<PayOrderInfoVO> otherPayOrderInfoVOs=new ArrayList<PayOrderInfoVO>();
        otherPayOrderInfoVOs=payOrderInfoService.loadPayOrderInfoVOByUserId(userId);
        for(PayOrderInfoVO payOrderInfoVO:otherPayOrderInfoVOs){
            if(payOrderInfoVO.getOrderStatus()==OrderType.REVIEWORDER||      //其他产品有在审核中或者在放款中的状态
                    payOrderInfoVO.getOrderStatus()==OrderType.LENDINGORDER||
                    payOrderInfoVO.getOrderStatus()==OrderType.APPROVEDORDER){
                singleLoanPageResponse.setStatus(3);
              return singleLoanPageResponse;
            }
        }
        //可贷状态
        singleLoanPageResponse.setStatus(4);
        return singleLoanPageResponse;
    }

    public LightLoanPageResponse getLightLoanPageData(String userId){
        LightLoanPageResponse lightLoanPageResponse=new LightLoanPageResponse();
        //查询这个人闪电贷的状态
        List<Integer> status=new  ArrayList<Integer>();
        List<Integer> types=new ArrayList<Integer>();
        types= this.getList("2");
        status=this.getList("0,1,5,6,8,9");
      List<PayOrderInfoVO> payOrderInfoVOs=payOrderInfoService.loadVOByStatusAndType(userId,status,types);
      for(PayOrderInfoVO payOrderInfoVO:payOrderInfoVOs){
         //审核中
         if(OrderType.REVIEWORDER==payOrderInfoVO.getOrderStatus()){
             lightLoanPageResponse.setStatus(2);
         } else if(OrderType.LENDINGORDER==payOrderInfoVO.getOrderStatus()||
                 OrderType.APPROVEDORDER==payOrderInfoVO.getOrderStatus()){
             //lightLoanPageResponse.setApplyTime(payOrderInfoVO.getApprovedTime().getTime());  //批准时间
             lightLoanPageResponse.setApprovedTime(payOrderInfoVO.getApprovedTime().getTime());
             lightLoanPageResponse.setStatus(1);
         } else if(OrderType.OVERDUEPAYMENT==payOrderInfoVO.getOrderStatus()||
                 OrderType.NOREIMBURSEMENT==payOrderInfoVO.getOrderStatus()){//贷还款
             //lightLoanPageResponse.setApplyTime(payOrderInfoVO.getApprovedTime().getTime());
             lightLoanPageResponse.setApprovedTime(payOrderInfoVO.getApprovedTime().getTime());
             lightLoanPageResponse.setLendTime(payOrderInfoVO.getLendTime().getTime());
             logger.info("========"+(int)DateUtil.dateNum(payOrderInfoVO.getLendTime(), Calendar.getInstance().getTime()));
             lightLoanPageResponse.setRemainDay(payOrderInfoVO.getLoadDays()-(int)DateUtil.getIntervalDay(payOrderInfoVO.getLendTime(), Calendar.getInstance().getTime()));
             lightLoanPageResponse.setOrderNo(payOrderInfoVO.getOrderNo());
             lightLoanPageResponse.setStatus(0);
         }else if(OrderType.REPAYING == payOrderInfoVO.getOrderStatus()){
             lightLoanPageResponse.setApprovedTime(payOrderInfoVO.getApprovedTime().getTime());
             lightLoanPageResponse.setLendTime(payOrderInfoVO.getLendTime().getTime());
             lightLoanPageResponse.setStatus(5);
         }
          lightLoanPageResponse.setLoanAmt(payOrderInfoVO.getLoanAmount());//贷款借款
          lightLoanPageResponse.setOrderAmt(payOrderInfoVO.getOrderAmount());//贷款钱数加利息
          lightLoanPageResponse.setOverdueFee(payOrderInfoVO.getOverdueFee());//逾期费
          lightLoanPageResponse.setOverdueDays(payOrderInfoVO.getOverdueDays());//逾期天数
          lightLoanPageResponse.setLoadDays(payOrderInfoVO.getLoadDays());  //贷款天数
          lightLoanPageResponse.setApplyTime(payOrderInfoVO.getCreatedAt().getTime());//申请时间
          return lightLoanPageResponse;
     }
        //查找这个人其他产品在放款之前的状态
        LightLoanProductInfo lightLoanProductInfo=customerProduceService.getLightLoanProductInfo();
        String productLimit=lightLoanProductInfo.getProductLimit();
        String[] strLimits=productLimit.split(",");
        List<Integer> limitList=new ArrayList<Integer>();
        for(String str:strLimits){
            limitList.add(Integer.parseInt(str));
        }
        lightLoanPageResponse.setLimitList(limitList);
        lightLoanPageResponse.setMinLoanDay(lightLoanProductInfo.getMinLoanDay());
        lightLoanPageResponse.setMaxLoanDay(lightLoanProductInfo.getMaxLoanDay());
        lightLoanPageResponse.setLightRate(lightLoanProductInfo.getLightRate());
        lightLoanPageResponse.setBaseRate(lightLoanProductInfo.getBaseRate ());
        lightLoanPageResponse.setNumberGradient(lightLoanProductInfo.getNumberGradient());

        status=this.getList("0,1,8");
        types=this.getList("1,3");
        List<PayOrderInfoVO> payOrderInfoVOther=new ArrayList<PayOrderInfoVO>();
        payOrderInfoVOther= payOrderInfoService.loadVOByStatusAndType(userId,status,types);
        if(payOrderInfoVOther.size()>0){
            lightLoanPageResponse.setStatus(3);
            return lightLoanPageResponse;
        }else{
            lightLoanPageResponse.setStatus(4);
        }
        return lightLoanPageResponse;
    }


    public OrderResponse getZeroDays(int type,String userId){
        OrderResponse orderResponse=new OrderResponse();
        ZeroDayInfo zeroDayInfo=zeroDayInfoService.getZeroDayInfoByUserIdAndType(userId,type);
        if(zeroDayInfo==null||(zeroDayInfo!=null&&zeroDayInfo.getZeroDay()==0)){
            orderResponse.setCode(ReturnClientStatus.SUCCESS);
            //return orderResponse;
        }else{
            int zeroDay=zeroDayInfo.getZeroDay();
            Date zeroDayStartTime=zeroDayInfo.getZeroDayStartDate();
            int dateNum=DateUtil.dateNum(zeroDayStartTime,new Date());
            if(zeroDay>dateNum){
                orderResponse.setCode(ReturnClientStatus.FAIL);
            }else{
                orderResponse.setCode(ReturnClientStatus.SUCCESS);
            }
        }
       return orderResponse;
    }

    public  CalculateLoanAmtResponse  calculateLoanAmt(PayOrderInfoForm payOrderInfoForm){
        CalculateLoanAmtResponse calculateLoanAmtResponse=new CalculateLoanAmtResponse();
        Integer loanDay=payOrderInfoForm.getLoadDays();
        int loanType=payOrderInfoForm.getBorrowType();
        Integer loanAmt=payOrderInfoForm.getLoanAmount();
        Map<String,Integer> rate=this.getRateByType(payOrderInfoForm.getBorrowType(),payOrderInfoForm.getUserId());
        Map<String,Integer> map=new HashMap<String,Integer>();
        Integer baseRateInteger=rate.get("baseRate");              //基本利率的integer类型
        Integer interestRateAmtInteger=rate.get("interestRate");   //总利率的integer类型
        if(payOrderInfoForm.getBorrowType()==BorrowType.SINGLELOAN){
            calculateLoanAmtResponse= CalculateLoanAmt.calculateLoanSingleAmt(baseRateInteger,interestRateAmtInteger,loanAmt,loanDay);
        }else if(payOrderInfoForm.getBorrowType()==BorrowType.LIGHTLOAN){
            calculateLoanAmtResponse= CalculateLoanAmt.calculateLoanLightAmt(baseRateInteger,interestRateAmtInteger,loanAmt,loanDay);
        }else {

        }
        return calculateLoanAmtResponse;
    }

    private Map<String,Integer> getRateByType(int type,String userId){
        Map<String,Integer> map=new HashMap<String,Integer>();
        CustomerCreditResult customerCreditResult=customerCreditResultService.loadVOByUserId(userId);
        int signaTotalRate=customerCreditResult.getSingleRate();
        int baseRate=0;
        int interestRate=0;
        if(type==BorrowType.SINGLELOAN){
            SingleLoanProductInfo singleLoanProductInfo =customerProduceService.getSingleLoanProductInfo();
            baseRate= singleLoanProductInfo.getBaseRate();   //基本利率
            interestRate=signaTotalRate;       //总利率
        }else if(type==BorrowType.LIGHTLOAN){
            LightLoanProductInfo lightLoanProductInfo=customerProduceService.getLightLoanProductInfo();
            baseRate=lightLoanProductInfo.getBaseRate();
            interestRate=lightLoanProductInfo.getLightRate();
        }
        map.put("baseRate",baseRate);     //基本利率
        map.put("interestRate",interestRate);   //总利率
        return map;
    }

    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public OrderResponse placeOrder(PayOrderInfoForm payOrderInfoForm,String smsCode,String phone){
        UserAgent userAgent =this.getUserAgent();
        OrderResponse orderResponse=new OrderResponse();
        String userId=payOrderInfoForm.getUserId();
        Integer lockFlag=(Integer)dubboCacheManager.get(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
        if(lockFlag!=null&&lockFlag==1){
            orderResponse.setCode("-1");
            orderResponse.setMessage("订单处理中");
            return orderResponse;
        }
        dubboCacheManager.put(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId,1);
        //首先校验验证码
        boolean flag=veriFacade.verifyCode(phone,smsCode, AliSmsSecurityCodeTemplateEnum.SUBMIT_ORDER);
        if(!flag){
            orderResponse.setCode("60");
            dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
            return orderResponse;
        }
        //账号被冻结,理解为黑名单
        CustomerBlackListVO customerBlackListVO=customerBlackListService.loadVO(payOrderInfoForm.getUserId());
        if(customerBlackListVO!=null){
            orderResponse.setCode("10");
            dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
            return orderResponse;
        }
        //有逾期未还、或者审核中放款中
        List<PayOrderInfoVO> payOrderInfoVOs=new ArrayList<PayOrderInfoVO>();
        List<Integer> statuss=new ArrayList<>();
        statuss=this.getList("0,1,5");
        List<Integer> types=new ArrayList<>();
        types= this.getList("1,2,3");
        payOrderInfoVOs=payOrderInfoService.loadVOByStatusAndType(payOrderInfoForm.getUserId(),statuss,types);
        if(payOrderInfoVOs.size()>0){
            //逾期
            for(PayOrderInfoVO payOrderInfoVO:payOrderInfoVOs){
                if(payOrderInfoVO.getOrderStatus()==OrderType.OVERDUEPAYMENT){
                    orderResponse.setCode("20");
                    dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
                    return orderResponse;
                }
            }
            //审核中的
            orderResponse.setCode("40");
            dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
            return orderResponse;
        }
        //计算利息
        CustomerCreditResult customerCreditResult=customerCreditResultService.loadVOByUserId(payOrderInfoForm.getUserId());
        Map<String,Integer> rateMap=this.getRateByType(payOrderInfoForm.getBorrowType(),payOrderInfoForm.getUserId());
        int baseRate=rateMap.get("baseRate");
        int interestRate=rateMap.get("interestRate");
        int clientBaseRate=payOrderInfoForm.getBaseRate();
        int clientInterestRate=payOrderInfoForm.getInterestRate();
        if(baseRate!=clientBaseRate||interestRate!=clientInterestRate){
            orderResponse.setCode("30");
            dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
            return orderResponse;
        }
        //总额不足
        int totalAmt=customerCreditResult.getTotalAmt();
        int singleAmt=customerCreditResult.getSingleAmt();
        int installmentAmt=customerCreditResult.getInstallmentAmt();
        statuss=this.getList("5,6");
        types=this.getList(payOrderInfoForm.getBorrowType()+"");
        //单期贷所有的钱
        Integer orderSumAmt=payOrderInfoService.getSumAmtByUserIdByTypeByStatus(payOrderInfoForm.getUserId(),statuss,types);
        if(orderSumAmt==null){
            orderSumAmt=0;
        }
        if(payOrderInfoForm.getBorrowType()==BorrowType.SINGLELOAN){
            if(orderSumAmt+payOrderInfoForm.getLoanAmount()>totalAmt||orderSumAmt+payOrderInfoForm.getLoanAmount()>singleAmt){
                orderResponse.setCode("50");
                dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
                return orderResponse;
            }
        }
        //传入参数插入订单数据
        String orderNo=Sequence.getOrderNo(payOrderInfoForm.getBorrowType());
        payOrderInfoForm.setOrderNo(orderNo);
        SimpleUserInfo simpleUserInfo=userTool.getSimpleUserInfo(payOrderInfoForm.getUserId());
        payOrderInfoForm.setOrderStatus(OrderType.REVIEWORDER);
        payOrderInfoForm.setPhone(simpleUserInfo.getPhone());//设置电话号码
        this.setOrderChannel(userAgent,payOrderInfoForm);  //设置订单渠道
        payOrderInfoForm.setNewOldSign(payOrderInfoService.isnewOldSigns(payOrderInfoForm.getUserId()));//设置新旧用户
        boolean sign=this.confirmOrderRisk(payOrderInfoForm);
        if(sign){
            payOrderInfoService.savePayOrderInfo(payOrderInfoForm);
        }
        orderResponse.setCode("00");
        dubboCacheManager.evictCache(DubboCacheRegion.CACHE_ORDER_DEAL_LOCK,userId);
        return orderResponse;
    }

    private void setOrderChannel(UserAgent userAgent,PayOrderInfoForm payOrderInfoForm) {
        String clientType = UserAgentUtil.getClient(userAgent);
        if (clientType.equals(ClientType.IOS) || clientType.equals(ClientType.ANDROID)) {
            payOrderInfoForm.setLoanChannel(ClientType.APP);
        } else if (clientType.equals(clientType.equals(ClientType.H5))) {
            payOrderInfoForm.setLoanChannel(ClientType.H5);
        }
    }


    public boolean confirmOrderRisk(PayOrderInfoForm payOrderInfoForm){
        //封装参数
        ApplyLoanRequest calculationLimitRequest=new ApplyLoanRequest();
        logger.info("=============开始封装订单提交风控需要的数据==========================");
        calculationLimitRequest.setCustomerId(payOrderInfoForm.getUserId());
        calculationLimitRequest.setOrderId(payOrderInfoForm.getOrderNo());
        calculationLimitRequest.setBorrowType(payOrderInfoForm.getBorrowType()+"");
        calculationLimitRequest.setBorrowAmt(payOrderInfoForm.getLoanAmount()+"");
        logger.info("======================"+payOrderInfoForm.getOrderNo()+"=====================");
        logger.info("=============开始调用风控提交订单接口===========================");
        IdCardInfo idCardInfo=new IdCardInfo();
        idCardInfo.setPhoneNum(payOrderInfoForm.getPhone());
        calculationLimitRequest.setIdCardInfo(idCardInfo);
        boolean flag= riskManagerInteractionService.submitOrder(calculationLimitRequest);
        logger.info("=============调用风控提交订单接口完成===========================");
        //插入订单号与数据关联
        rabbitmqMessageSender.send(RabbitMqQueue.RABBIT_MQ_ORDER_STATISTICS,calculationLimitRequest,true);
        return flag;
    }

    /***
     * 风控的回调的接口
     * @param applyLoanResponse
     */
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER,propagation= Propagation.REQUIRED)
    public void callBackRisk(ApplyLoanResponse applyLoanResponse){
       // applyLoanResponse.setResultCode("00");
        riskManagerInteractionService.callBackSubmitOrder(applyLoanResponse);
        String resultCode=applyLoanResponse.getResultCode();  //结果码
        logger.info("=============="+resultCode+"=======================");
        String orderId=applyLoanResponse.getOrderId();   //订单的id
        logger.info("=============="+orderId+"=======================");
        String customerId=applyLoanResponse.getCustomerId();  //用户的id
        logger.info("=============="+customerId+"=======================");
        String  zeroDay=applyLoanResponse.getDelayDay();   //置零天数
        logger.info("=============="+zeroDay+"=======================");
        String type=applyLoanResponse.getBorrowType();   //借款类型
        logger.info("=============="+type+"=======================");
        int status=0;
        //获取订单
        PayOrderInfoVO payOrderInfo=payOrderInfoService.loadVOByOrderNo(orderId);
        //审核通过
        if(ReturnClientStatus.SUCCESS.equals(resultCode)){
            status=OrderType.APPROVEDORDER;
        }
        //审核失败
        else if(ReturnClientStatus.FAIL.equals(resultCode)){
            status=OrderType.AUDITFAILED;
        }
        //进入信审状态
        else if(ReturnClientStatus.ADUIT.equals(resultCode)){
            //插入信审表的数据
            CustomerCreditAuditForm customerCreditAuditForm=new CustomerCreditAuditForm();
            //customerCreditAuditForm.setUserId(orderId);
            customerCreditAuditForm.setAuditConclusion(null);
            customerCreditAuditForm.setAuditStatus(CreditAuditConstant.UNALLOCATED);
            customerCreditAuditForm.setAuditStatus(1);
            customerCreditAuditForm.setStatus(1);
            customerCreditAuditForm.setOrderId(orderId);
            customerCreditAuditService.save(customerCreditAuditForm);
            return;
        }
        logger.info("=============开始发送订单审核推送==================");
        this.sendAuditPushAndMsg(payOrderInfo,resultCode);
        logger.info("=============完成发送订单审核推送==================");
            //更新订单的数据
        logger.info("=============="+"更新订单审核数据"+"=======================");
        payOrderInfoService.updateOrderApprovedStatusByUserIdAndOrderNo(customerId,orderId,status);
        logger.info("=============="+"更新订单审核数据完成"+"=======================");
          //更新置零天数
        logger.info("=============="+"更新置零天数"+"=======================");
        if(type!=null&&Integer.parseInt(type)>=0){
        ZeroDayInfo zeroDayInfo=zeroDayInfoService.getZeroDayInfoByUserIdAndType(customerId,Integer.parseInt(type));
        if(zeroDayInfo!=null){
            zeroDayInfoService.updateZeroDayInfoByUserIdAndType(customerId,Integer.parseInt(type),Integer.parseInt(zeroDay));
        }else{
            zeroDayInfo=new ZeroDayInfo();
            zeroDayInfo.setZeroDay(Integer.parseInt(zeroDay));
            zeroDayInfo.setUserId(customerId);
            zeroDayInfo.setStatus(1);
            zeroDayInfo.setBorrowType(Integer.parseInt(type));
            zeroDayInfoService.insertZeroDayInfoByUserIdAndType(zeroDayInfo);
        }
        }
        logger.info("=============="+"更新置零天数完成"+"=======================");
        //如果执行成功  放款操作
        if(resultCode.equals(ReturnClientStatus.SUCCESS)){
            logger.info("==================开始发送支付订单到消息队列===========");
            rabbitmqMessageSender.send(RabbitMqQueue.RABBIT_MQ_PAY_ORDER,applyLoanResponse,true);
            logger.info("==================发送支付订单到消息队列完成============");
        }
    }


    public void playMoney(ApplyLoanResponse applyLoanResponse){
        String customerId=applyLoanResponse.getCustomerId();
        String  orderId=applyLoanResponse.getOrderId();
        //查询订单
        PayRequest request=new PayRequest();
        request.setOrderNo(orderId);
        request.setUserId(customerId);
        //单期贷
        String bizType=allinPayTransService.getPayBizType(orderId);
        if(SysStringUtils.isNotEmpty(bizType))
        {
            request.setBizType(bizType);
        }

        logger.info("====真正开始调用支付接口，订单的订单号为===="+orderId+"============");
        PayResult payResult = allinPayTransService.payFund(request);
        logger.info("===============真正调用支付接口完成====================");
    }

    /***
     * 发送审核通过或者失败的短信
     * @param payOrderInfo
     * @param resultCode
     */
    private void sendAuditPushAndMsg(PayOrderInfo payOrderInfo,String resultCode){
        CreditPushMsgBody creditPushMsgBody =new CreditPushMsgBody();
        logger.info("=============推送的客户id"+payOrderInfo.getUserId()+"======================");
        creditPushMsgBody.setAmount(payOrderInfo.getOrderAmount());
        creditPushMsgBody.addDstUserId(payOrderInfo.getUserId());
        if(ReturnClientStatus.SUCCESS.equals(resultCode)){
            creditPushMsgBody.setType(CreditPushConstant.PASS_AUDIT_TYPE);
        }else{
            creditPushMsgBody.setType(CreditPushConstant.NOT_PASS_AUDIT_TYPE);
        }
        creditPushMsgService.dealPush(creditPushMsgBody);
    }


    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void dealPayAfter(PayInformPara payInformPara){
        PayOrderInfoForm payOrderInfoForm=new PayOrderInfoForm();
        PayOrderInfoVO  payOrderInfoVO=payOrderInfoService.loadVOByOrderNo(payInformPara.getOrderId());
        BeanUtils.copyProperties(payOrderInfoVO,payOrderInfoForm);
        payOrderInfoForm.setId(payOrderInfoVO.getId());
        logger.info("啦啦啦啦啦"+payInformPara.getPayType());
        //打款
        if(PayType.LENDING == payInformPara.getPayType()){
              //开启quartz
             if(payInformPara.getState()== OrderPayState.STATE_SUCCESS){
                 logger.info("=============="+"放款成功开启定时任务"+"=======================");
                 this.startQuartz(payOrderInfoVO);
                 logger.info("=============="+"放款成功开启定时任务完成"+"=======================");
             }
              //发送推送
              //this.sendPayPushAndMsg(payInformPara,payOrderInfoVO);
        } else{//还款
            payOrderJobService.paySuccessful(payOrderInfoVO.getOrderNo());
//            //调用提额接口,一期先不调  二期在调
//            RaiseLimitRequest raiseLimitRequest = new RaiseLimitRequest();
//            raiseLimitRequest.setOrderId(payOrderInfoVO.getOrderNo());
//            raiseLimitRequest.setBorrowType(payOrderInfoVO.getBorrowType()+"");
//            raiseLimitRequest.setCustomerId(payOrderInfoVO.getUserId());
//            raiseLimitRequest.setStage("0");
//            riskManagerInteractionService.raiseLimit(raiseLimitRequest);
        }
        //发送推送
        this.sendPayPushAndMsg(payInformPara,payOrderInfoVO);
    }

    public void sendPayPushAndMsg(PayInformPara payInformPara,PayOrderInfoVO payOrderInfoVO){
        //推送和短信
        CreditPushMsgBody creditPushMsgBody =new CreditPushMsgBody();
        creditPushMsgBody.addDstUserId(payOrderInfoVO.getUserId());
        if(payInformPara != null){
            switch (payInformPara.getPayType()){
                case  PayType.LENDING ://借款
                    creditPushMsgBody.setOrderNo(payInformPara.getOrderId());
                    creditPushMsgBody.setShouldReturnTime(DateUtil.dateToString(payOrderInfoVO.getShouldReturnTime()));
                    creditPushMsgBody.setAmount(payOrderInfoVO.getLoanAmount());
                    if( OrderPayState.STATE_SUCCESS == payInformPara.getState()){
                        logger.info("==============借款成功类型=======================");
                        creditPushMsgBody.setType(CreditPushConstant.LEND_PASS_TYPE);
                    } else {
                        logger.info("==============借款成功类型=======================");
                        creditPushMsgBody.setType(CreditPushConstant.NOT_LEND_PASS_TYPE);
                    }
                    break;
                case  PayType.REPAYMENT://还款
                    creditPushMsgBody.setAmount(payOrderInfoVO.getOrderAmount()+payOrderInfoVO.getOverdueFee());
                    if( OrderPayState.STATE_SUCCESS == payInformPara.getState()){
                        logger.info("==============还款成功类型=======================");
                        creditPushMsgBody.setType(CreditPushConstant.REPAY_SUCCESS_TYPE);
                    } else {
                        logger.info("==============还款失败类型=======================");
                        creditPushMsgBody.setType(CreditPushConstant.REPAY_FAIL_TYPE);
                    }
                    break;
                default:
                    break;
            }
        }
        creditPushMsgService.dealPush(creditPushMsgBody);
    }

    public void startQuartz(PayOrderInfoVO payOrderInfo){
        int hour=Integer.parseInt(SpringPropertiesUtil.getPropertiestValue("credit.reminder.hour"));
        String orderNo=payOrderInfo.getOrderNo();
        Date lateDate=DateUtil.getDateHourMinuteSecond(payOrderInfo.getShouldReturnTime(),00,00,00);
        Date reminderDate=DateUtil.getDateHourMinuteSecond(payOrderInfo.getShouldReturnTime(),hour,00,00);
        Date lateDateUtil=DateUtil.addDays(lateDate,1);
        Date remindDateUtil=DateUtil.addDays(reminderDate,-2);
        //创建两个定时任务  1、到期还款的定时  2 、定时还款
        //到期还款的定时
        OrderJobParams orderJobParams=new OrderJobParams();
        orderJobParams.setTaskType(TaskEnum.REFUND_EXPIRERE_JOB);
        orderJobParams.setOrderNo(orderNo);
        orderJobParams.setOrderExpireTime(lateDateUtil);
        payOrderJobService.createExpireRefundJob(orderJobParams);
        //定时还款提醒
        OrderJobParams orderReminderJobParams=new OrderJobParams();
        orderReminderJobParams.setTaskType(TaskEnum.REMINDER_REFUND_JOB);
        orderReminderJobParams.setOrderNo(orderNo);
        orderReminderJobParams.setOrderExpireTime(remindDateUtil);
        payOrderJobService.createExpireRefundJob(orderReminderJobParams);
    }



    @Override
    public void sendMqFromRiskConfirmOrder(ApplyLoanResponse applyLoanResponse){
        rabbitmqMessageSender.send(RabbitMqQueue.RABBIT_MQ_RISK_COMFIRM_ORDER,applyLoanResponse,true);
    }

    @Override
    public void sendMqFromRaiseLimit(RaiseLimitResponse raiseLimitResponse) {
        rabbitmqMessageSender.send(RabbitMqQueue.RABBIT_MQ_RAISE_LIMIT,raiseLimitResponse,true);
    }

    private List<Integer> getList(String str){
        List<Integer>  lists=new ArrayList<Integer>();
        if(str.length()>1) {
          String[] strs=str.split(",");
          for(String item:strs){
              lists.add(Integer.parseInt(item));
          }
        }else{
            lists.add(Integer.parseInt(str));
        }
        return lists;
    }

    /***
     * 还款的逻辑
     * @param payOrderInfoVO
     * @param mixCardNo
     * @return
     */
    public PayResult repayMoney(PayOrderInfoVO payOrderInfoVO,String mixCardNo){
        PayRequest request=new PayRequest();
        request.setUserId(payOrderInfoVO.getUserId());
        request.setOrder(payOrderInfoVO);
        request.setMixCardNo(mixCardNo);

        String orderId=payOrderInfoVO.getOrderNo();
        //单期贷
        String bizType=allinPayTransService.getPayBizType(orderId);
        if(SysStringUtils.isNotEmpty(bizType))
        {
            request.setBizType(bizType);
        }
        PayResult payResult = allinPayTransService.repayFund(request);
        return payResult;
    }

    public CustomerBankCardInfoVO getRepayCardInfo(PayOrderInfoVO payOrderInfoVO, String mixCard,String transCode){
        CustomerBankCardInfoVO customerBankCardInfoVO = customerBankCardInfoService.loadVOByUserIdAndMixCardNo(payOrderInfoVO.getUserId(),mixCard);

        if(TransRequestCode.TRX_CODE_REPAY.equals(transCode))
        {
            dubboCacheManager.put(DubboCacheRegion.CACHE_REPAY_BANK_CARD_NO,customerBankCardInfoVO,
                    payOrderInfoVO.getOrderNo()+payOrderInfoVO.getUserId());
            //jedisUtil.setObject(payOrderInfoVO.getOrderNo()+payOrderInfoVO.getUserId(), JSON.toJSONString(customerBankCardInfoVO));
            logger.info("=========放入缓存的数据的key为"+payOrderInfoVO.getOrderNo()+payOrderInfoVO.getUserId()+"=========");
            logger.info("=========放入缓存的数据的为"+JSON.toJSONString(customerBankCardInfoVO)+"=========");
        }
        return customerBankCardInfoVO;
    }


    public static void main(String[] args) throws Exception{

//         //long l= 1502154000464l;
//        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Long time=new Long(1502985600000l);
//        String d = format.format(time);
//        Date date=format.parse(d);
//        System.out.println("Format To String(Date):"+d);
//        System.out.println("Format To Date:"+date);

        System.out.println(DESC.encrypt3DES("6228480750368060117"));


    }



}
